package com.atguigu.tingshu.common.login;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.concurrent.TimeUnit;

/**
 * ClassName: TsLoginAspect
 * Package: com.atguigu.tingshu.common.login
 * Description:
 *
 * @Author:
 * @Create: 2025/7/22 - 16:39
 * @Version: v1.0
 */
@Component
@Aspect
public class TsLoginAspect {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Around("execution(* com.atguigu.tingshu.*.api.*.*(..)) && @annotation(tsLogin)")
    public Object loginAspect(ProceedingJoinPoint joinPoint, TsLogin tsLogin) {
        //获取请求头对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes= (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        //从请求头对象里获取token值
        String token = request.getHeader("token");
        //判断token是否为空
        if (tsLogin.required() && !StringUtils.hasText(token)) {
            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }
        String key = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
        if (StringUtils.hasText(token)) {
            //如果不为空，则查询redis里的数据
            String redisJson = stringRedisTemplate.opsForValue().get(key);
            if (!StringUtils.hasText(redisJson)) {
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }
            UserInfo userInfo = JSONObject.parseObject(redisJson, UserInfo.class);
            if (userInfo != null) {
                AuthContextHolder.setUserId(userInfo.getId());
                AuthContextHolder.setUsername(userInfo.getNickname());
            }
        }
        //将token进行续期
        stringRedisTemplate.expire(key,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
        //  执行业务逻辑
        try {
            return joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}
